#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
#include <set>
#include <cctype>

using namespace std;

int W, H, N;
char IMAP[16][16];
vector<int> G[256];
int z0[3];
int z1[3];
bool vis[16777220];


struct Node {
    int z;
    int deep;
    //vector<int> his;
};

void input() {
    int N_Arr[26];
    memset(N_Arr, 0xFF, sizeof(N_Arr));
    int N_Ind = 0;
    for (int i=0; i<256; i++) {
        G[i].clear();
        G[i].push_back(i);
    }
    memset(IMAP, 0, sizeof(IMAP));
    for (int i=0; i<H; i++) {
        for (int j=0; j<W; j++) {
            char c = getchar();
            int z = i*W+j;
            if (c == ' ' || isalpha(c)) {
                IMAP[i][j] = 1;
                if (i-1 >= 0 && IMAP[i-1][j] == 1) { //Up
                    int z1 = (i-1)*W+j;
                    G[z1].push_back(z);
                    G[z].push_back(z1);
                }
                if (j-1 >= 0 && IMAP[i][j-1] == 1) { //Left
                    int z1 = i*W+(j-1);
                    G[z1].push_back(z);
                    G[z].push_back(z1);
                }
            }
            if (islower(c)) {
                if (N_Arr[c-'a'] < 0) {
                    N_Arr[c-'a'] = N_Ind++;
                }
                z1[N_Arr[c-'a']] = i*W+j;
            } else if (isupper(c)) {
                if (N_Arr[c-'A'] < 0) {
                    N_Arr[c-'A'] = N_Ind++;
                }
                z0[N_Arr[c-'A']] = i*W+j;
            }
        }
        getchar();
    }
//    printf("\n\n");
//    for (int i=0; i<H; i++) {
//        for (int j=0; j<W; j++) {
//            printf("%d", IMAP[i][j]);
//        }
//        printf("\n");
//    }
}

int get_hash(int *z) {
    return (z[0]<<16) | (z[1]<<8) | (z[2]);
}

//int print(int h) {
//    for (int i=16; i>=0; i-=8) {
//        int n = (h>>i) & 0xFF;
//        int x = n/W;
//        int y = n%W;
//        printf("%d %d | ", x, y);
//    }
//    printf("\n");
//}

int bfs() {
    queue<Node> q;
    memset(vis, 0, sizeof(vis));
    Node start;
    //start.z[0] = z1[0]; start.z[1] = z1[1]; start.z[2] = z1[2];
    start.z = get_hash(z1);
    start.deep = 0;
    //start.his.push_back(get_hash(start.z));
    q.push(start);
    vis[start.z] = true;

    while (!q.empty()) {
        Node n = q.front(); q.pop();
        //print(n);
        Node x;
        int xz[3] = {0}, nz[3];
        for (int i=2; i>=0; i--) {
            int aa = (n.z>>(i*8)) & 0xFF;
            nz[2-i] = aa;
        }
        bool ok = true;
        for (int i=0; i<N; i++) {
            if (nz[i] != z0[i]) {
                ok = false;
                break;
            }
        }
        if (ok) {
            return n.deep;
        }
        //printf("%d %d %d | %d\n", nz[0], nz[1], nz[2], n.deep);
        x.deep = n.deep + 1;
        for (int i=0; i<G[nz[0]].size(); i++) {
            xz[0] = G[nz[0]][i];
            if (N > 1) {
                for (int j=0; j<G[nz[1]].size(); j++) {
                    xz[1] = G[nz[1]][j];
                    if (N > 2) {
                        for (int k=0; k<G[nz[2]].size(); k++) {
                            xz[2] = G[nz[2]][k];
                            x.z = get_hash(xz);
                            if (!vis[x.z] && !(xz[0]==xz[1] || xz[1]==xz[2] || xz[0]==xz[2])) {
                                if (xz[0]==nz[1] && xz[1]==nz[0]) continue;
                                if (xz[1]==nz[2] && xz[2]==nz[1]) continue;
                                if (xz[0]==nz[2] && xz[2]==nz[0]) continue;
                                //x.his = n.his;
                                //x.his.push_back(get_hash(x.z));
                                vis[x.z] = true;
                                q.push(x);
                            }
                        }
                    } else {
                        x.z = get_hash(xz);
                        if (!vis[x.z] && xz[0]!=xz[1]) {
                            if (xz[0]==nz[1] && xz[1]==nz[0]) continue;
                            //printf("Bingo!\n");
                            vis[x.z] = true;
                            q.push(x);
                        }
                    }
                }
            } else {
                x.z = get_hash(xz);
                if (!vis[x.z]) {
                    vis[x.z] = true;
                    q.push(x);
                }
            }
        }
    }

    return -1;
}

int main()
{
    while (~scanf("%d%d%d", &W, &H, &N)) {
        if (!(W || H || N)) break;
        getchar();
        input();
        int ans = bfs();
        printf("%d\n", ans);
    }
    return 0;
}
